package com.voe;

import com.voe.common.OutputParam;
import com.voe.common.ReturnValue;

/**This sub-API supports the following functionalities:<br/>
*<br/>
*- Speaker volume controls.<br/>
*- Microphone volume control.<br/>
*- Non-linear speech level control.<br/>
*- Mute functions.<br/>
*- Additional stereo scaling methods.<br/>
*<br/>
*Usage example, omitting error checking:<br/>
*<br/>
*VoiceEngine voe = VoiceEngine.createInterface();<br/>
*VoEBase base = VoEBase.createInterface(voe);<br/>
*VoEVolumeControl volume  = VoEVolumeControl.createInterface(voe);<br/>
*base.init();<br/>
*int ch = base.createChannel();<br/>
*...<br/>
*volume.setInputMute(ch, true);<br/>
*...<br/>
*base.deleteChannel(ch);<br/>
*base.terminate();<br/>
*base.release();<br/>
*volume.release();<br/>
*voe.release();<br/>
*/
public class VoEVolumeControl {

	// [start] apis
	
	public static VoEVolumeControl createInstance(VoiceEngine voiceEngine) {

		long p = GetInterface(voiceEngine._p);
		if(p != 0)
			return new VoEVolumeControl(p);
		return null;
	}

	public void release() {
		if (_p != 0) {
			Release(_p);
		}
	}
	
	/** Sets the speaker |volume| level. Valid range is [0,255].
	 */
	public int setSpeakerVolume(int volume) {
		return SetSpeakerVolume(_p, volume);
	}

	/** Gets the speaker |volume| level.
	 */
	public int getSpeakerVolume(ReturnValue<Integer> volume) {
		OutputParam output = new OutputParam();
		int result = GetSpeakerVolume(_p, output);
		if(result == 0) {
			volume.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Mutes the speaker device completely in the operating system.
	 */
	public int setSystemOutputMute(boolean enable) {
		return SetSystemOutputMute(_p, enable); 
	}

	/** Gets the output device mute state in the operating system.
	 */
	public int getSystemOutputMute(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetSystemOutputMute(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
		}
		return result;
	}

	/** Sets the microphone volume level. Valid range is [0,255].
	 */
	public int setMicVolume(int volume) {
		return SetMicVolume(_p, volume); 
	}

	/** Gets the microphone volume level.
	 */
	public int getMicVolume(ReturnValue<Integer> volume) {
		OutputParam output = new OutputParam();
		int result = GetMicVolume(_p, output);
		if(result == 0) {
			volume.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Mutes the microphone input signal completely without affecting<br/>
	 *  the audio device volume.
	 */
	public int setInputMute(int channel, boolean enable) {
		return SetInputMute(_p, channel, enable); 
	}

	/** Gets the current microphone input mute state.
	 */
	public int getInputMute(int channel, ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetInputMute(_p, channel, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
		}
		return result;
	}

	/** Mutes the microphone device completely in the operating system.
	 */
	public int setSystemInputMute(boolean enable) {
		return SetSystemInputMute(_p, enable); 
	}

	/** Gets the mute state of the input device in the operating system.
	 */
	public int getSystemInputMute(ReturnValue<Boolean> enabled) {
		OutputParam output = new OutputParam();
		int result = GetSystemInputMute(_p, output);
		if(result == 0) {
			enabled.setValue((Boolean)output.getObject()[0]);
		}
		return result;
	}

	/** Gets the microphone speech |level|, mapped non-linearly to the range<br/>
	 *  [0,9].
	 */
	public int getSpeechInputLevel(ReturnValue<Integer> level) {
		OutputParam output = new OutputParam();
		int result = GetSpeechInputLevel(_p, output);
		if(result == 0) {
			level.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Gets the speaker speech |level|, mapped non-linearly to the range<br/>
	 *  [0,9].
	 */
	public int getSpeechOutputLevel(int channel, ReturnValue<Integer> level) {
		OutputParam output = new OutputParam();
		int result = GetSpeechOutputLevel(_p, channel, output);
		if(result == 0) {
			level.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Gets the microphone speech |level|, mapped linearly to the range<br/>
	 *  [0,32768].
	 */
	public int getSpeechInputLevelFullRange(ReturnValue<Integer> level) {
		OutputParam output = new OutputParam();
		int result = GetSpeechInputLevelFullRange(_p, output);
		if(result == 0) {
			level.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Gets the speaker speech |level|, mapped linearly to the range [0,32768].
	 */
	public int getSpeechOutputLevelFullRange(int channel, ReturnValue<Integer> level) {
		OutputParam output = new OutputParam();
		int result = GetSpeechOutputLevelFullRange(_p, channel, output);
		if(result == 0) {
			level.setValue((Integer)output.getObject()[0]);
		}
		return result;
	}

	/** Sets a volume |scaling| applied to the outgoing signal of a specific<br/>
	 *  channel. Valid scale range is [0.0, 10.0].
	 */
	public int setChannelOutputVolumeScaling(int channel, float scaling) {
		return SetChannelOutputVolumeScaling(_p, channel, scaling); 
	}

	/** Gets the current volume scaling for a specified |channel|.
	 */
	public int getChannelOutputVolumeScaling(int channel, ReturnValue<Float> scaling) {
		OutputParam output = new OutputParam();
		int result = GetChannelOutputVolumeScaling(_p, channel, output);
		if(result == 0) {
			scaling.setValue((Float)output.getObject()[0]);
		}
		return result;
	}

	/** Scales volume of the |left| and |right| channels independently.<br/>
	 *  Valid scale range is [0.0, 1.0].
	 */
	public int setOutputVolumePan(int channel, float left, float right) {
		return SetOutputVolumePan(_p, channel, left, right); 
	}

	/** Gets the current left and right scaling factors.
	 */
	public int getOutputVolumePan(int channel, ReturnValue<Float> left, ReturnValue<Float> right) {
		OutputParam output = new OutputParam();
		int result = GetOutputVolumePan(_p, channel, output);
		if(result == 0) {
			left.setValue((Float)output.getObject()[0]);
			right.setValue((Float)output.getObject()[1]);
		}
		return result;
	}	

	protected VoEVolumeControl(long p) {
		_p = p;
	}

	protected long _p;
	
	//[end]
	
	
	
	
	
	
	

	// [start] jni api

	// Factory for the VoEVolumeControl sub-API. Increases an internal
	// reference counter if successful. Returns NULL if the API is not
	// supported or if construction fails.
	private static native long GetInterface(long p_voiceEngine);

	// Releases the VoEVolumeControl sub-API and decreases an internal
	// reference counter. Returns the new reference count. This value should
	// be zero for all sub-API:s before the VoiceEngine object can be safely
	// deleted.
	private static native int Release(long p_VoEVolumeControl);

	// Sets the speaker |volume| level. Valid range is [0,255].
	private static native int SetSpeakerVolume(long p_VoEVolumeControl,
			int volume);

	// Gets the speaker |volume| level.
	private static native int GetSpeakerVolume(long p_VoEVolumeControl,
			OutputParam volume);

	// Mutes the speaker device completely in the operating system.
	private static native int SetSystemOutputMute(long p_VoEVolumeControl,
			boolean enable);

	// Gets the output device mute state in the operating system.
	private static native int GetSystemOutputMute(long p_VoEVolumeControl,
			OutputParam enabled);

	// Sets the microphone volume level. Valid range is [0,255].
	private static native int SetMicVolume(long p_VoEVolumeControl, int volume);

	// Gets the microphone volume level.
	private static native int GetMicVolume(long p_VoEVolumeControl,
			OutputParam volume);

	// Mutes the microphone input signal completely without affecting
	// the audio device volume.
	private static native int SetInputMute(long p_VoEVolumeControl,
			int channel, boolean enable);

	// Gets the current microphone input mute state.
	private static native int GetInputMute(long p_VoEVolumeControl,
			int channel, OutputParam enabled);

	// Mutes the microphone device completely in the operating system.
	private static native int SetSystemInputMute(long p_VoEVolumeControl,
			boolean enable);

	// Gets the mute state of the input device in the operating system.
	private static native int GetSystemInputMute(long p_VoEVolumeControl,
			OutputParam enabled);

	// Gets the microphone speech |level|, mapped non-linearly to the range
	// [0,9].
	private static native int GetSpeechInputLevel(long p_VoEVolumeControl,
			OutputParam level);

	// Gets the speaker speech |level|, mapped non-linearly to the range
	// [0,9].
	private static native int GetSpeechOutputLevel(long p_VoEVolumeControl,
			int channel, OutputParam level);

	// Gets the microphone speech |level|, mapped linearly to the range
	// [0,32768].
	private static native int GetSpeechInputLevelFullRange(
			long p_VoEVolumeControl, OutputParam level);

	// Gets the speaker speech |level|, mapped linearly to the range [0,32768].
	private static native int GetSpeechOutputLevelFullRange(
			long p_VoEVolumeControl, int channel, OutputParam level);

	// Sets a volume |scaling| applied to the outgoing signal of a specific
	// channel. Valid scale range is [0.0, 10.0].
	private static native int SetChannelOutputVolumeScaling(
			long p_VoEVolumeControl, int channel, float scaling);

	// Gets the current volume scaling for a specified |channel|.
	private static native int GetChannelOutputVolumeScaling(
			long p_VoEVolumeControl, int channel, OutputParam scaling);

	// Scales volume of the |left| and |right| channels independently.
	// Valid scale range is [0.0, 1.0].
	private static native int SetOutputVolumePan(long p_VoEVolumeControl,
			int channel, float left, float right);

	// Gets the current left and right scaling factors.
	private static native int GetOutputVolumePan(long p_VoEVolumeControl,
			int channel, OutputParam param);

	// [end]
}
